package com.example.basic.utils;

import com.example.basic.exception.ServiceException;
import com.example.basic.exception.TokenValidationException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;


public class JwtUtil {
    private static final long EXPIRATION_TIME = 3600000; // 1 hour 的时间单位
    private static final String SECRET = "1_@_BAJIAO_@_1";
    public static final String TOKEN_PREFIX = "Bearer";
    public static final String HEADER_STRING = "Authorization";

    public static String generateToken(Map<String, Object> map) {
        return generateToken(map, null);
    }

    public static String generateToken(Map<String, Object> map,String randomValue) {
        long tokenExpTime = Long.valueOf(map.get("tokenExpTime").toString());
        if (tokenExpTime == 0){
            tokenExpTime = EXPIRATION_TIME;
        }
        if(randomValue != null){//防重复提交
            map.put("randomValue",randomValue);
        }
        String jwt = Jwts.builder()
                .setClaims(map)
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpTime))
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .compact();
        return jwt;
    }

    public static Map<String, Object> validateToken(String token) {
        Map<String, Object> resultmap = new HashMap<String, Object>();
        if (StringUtils.isNotEmpty(token)) {
            // parse the token.
            Map<String,Object> body = new HashMap<>();
            try{
                body = Jwts.parser()
                        .setSigningKey(SECRET)
                        .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
                        .getBody();
            }catch (Exception e){
                throw new ServiceException("令牌错误!");
            }
            String loginName = (String) body.get("loginName");
            String userName = (String) (body.get("userName"));
            String userCode = (String) (body.get("userCode"));

            long expiryTime = (long) body.get("expiryTime");
            long tokenExpTime = ((Number) body.get("tokenExpTime")).longValue();

            resultmap.put("userCode",userCode);
            resultmap.put("loginName",loginName);
            resultmap.put("userName",userName);
            resultmap.put("expiryTime",String.valueOf(expiryTime));
            resultmap.put("tokenExpTime",String.valueOf(tokenExpTime));
            if(expiryTime > System.currentTimeMillis()){
                //过期前10分钟有操作，则更新有效期
                if(expiryTime - System.currentTimeMillis() < 10*60*1000){
                    String jwt = generateToken(resultmap);
                    resultmap.put("newJwt",jwt);
                }
            }else{
                throw new ServiceException("token已经过期!");
            }

            if (loginName == null || loginName.isEmpty()) {
//                throw new TokenValidationException("Wrong token without userName");
                return null;
            } else {
                return resultmap;
            }
        }else{
            throw new TokenValidationException("Missing token");
        }
    }


}
